package com.hznu.coursemanagerbackend.common.cryptolib;

import java.util.Random;

/**
 * Created by hb on 2015/11/20.
 */
public class CryptoApp
{
    private final static byte nSalt = 8;
    /*-------------user password process------------
    this process returns a unit containing code stored in DB and the associate salt value
    1. generate a nSalt-bytes salt
    2. splice the password and salt into a single unit
    3. hash the unit with SM3 and save the first 128 bits as encrypt key
    4. encrypt 0 with the above key using SM4
     */
    public static PsdProcRlt PwdProcess(byte[] pwd) throws Exception
    {
        if(pwd.length == 0)
            throw new Exception("Password string empty exception!");

        if(pwd == null)
            throw new Exception("Password null exception!");

        PsdProcRlt rlt = new PsdProcRlt();
        Random rn = new Random();

        //generate a 2-bytes salt
        rn.nextBytes(rlt.getSalt());

        //splice
        byte[] temp = new byte[pwd.length + nSalt];

        System.arraycopy(pwd, 0, temp, 0, pwd.length);
        System.arraycopy(rlt.getSalt(), 0, temp, pwd.length, nSalt);

        //hash
        byte[] key = new byte[16];
        System.arraycopy(SM3.hash(temp), 0, key, 0, 16);

        SM4 s = new SM4();

        s.Init(s.ECB, key, null);
        s.Ecb_Encrypt(rlt.getValue());

        return rlt;
    }

    /*------translate password and salt into the code stored in DB-------*/
    public static byte[] PwdTransValue(byte[] pwd, byte[] salt) throws Exception
    {
        if(pwd.length == 0)
            throw new Exception("Password string empty exception!");

        if(pwd == null)
            throw new Exception("Password null exception!");

        if(salt.length != nSalt)
            throw new Exception("Salt length invalid exception!");

        //splice
        byte[] temp = new byte[pwd.length + nSalt];

        System.arraycopy(pwd, 0, temp, 0, pwd.length);
        System.arraycopy(salt, 0, temp, pwd.length, nSalt);

        //hash
        byte[] key = new byte[16];
        System.arraycopy(SM3.hash(temp), 0, key, 0, 16);

        SM4 s = new SM4();
        byte[] value = new byte[16];

        s.Init(s.ECB, key, null);
        s.Ecb_Encrypt(value);

        return value;
    }
    //CBC模式，PKCS5模式padding
    public static byte[] SM4Enc(byte[] ptext, byte[] key, byte[] iv)
    {
        byte[] ctext = null;
        SM4 s = new SM4();
        s.Init(s.CBC, key, iv);


        return ctext;
    }

    public static byte[] SM4Dec(byte[] ctext, byte[] key, byte[] iv)
    {
        byte[] ptext = null;

        SM4 s = new SM4();
        s.Init(s.CBC, key, iv);



        return ptext;
    }
}

